﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharePoint2007Migration.Domain.Collections;
using Microsoft.SharePoint;
using System.Collections.Specialized;
using System.Xml;

namespace SharePoint2007Migration.Domain
{
    public class MissingFeatureReport : BaseReport
    {
        public MissingFeatureReport(MissingFeatureIssueCollection ft)
            : base(ft.ToIssueCollection())
        {
            this.MissingFeatureIssueCollection = ft;

        }

        public MissingFeatureIssueCollection MissingFeatureIssueCollection { get; private set; }

        public string GetResolvedFeaturesInformations()
        {
            FeatureCollection allFeaturesInContentDb = GetAllFeaturesFromCurrentContentDb();
            FeatureCollection FeaturesResolved = new FeatureCollection();
            StringBuilder result = new StringBuilder();

            foreach (MissingFeatureIssue missingFeatureIssue in this.MissingFeatureIssueCollection)
            {
                try
                {
                    Feature feature = allFeaturesInContentDb[missingFeatureIssue.FeatureId];
                    if (feature != null)
                        FeaturesResolved.Add(feature);
                }
                catch (Exception)
                {
                    ;//handle better...
                }
            }
            result.AppendLine(CreateIssueCountInformations(this.MissingFeatureIssueCollection.Count, FeaturesResolved.Count, 
                allFeaturesInContentDb.Count, "Feature"));

            // print details of each feature
            foreach (var item in FeaturesResolved)
                result.AppendLine(item.Value.ToString());
           
            return result.ToString();
        }

      
        public FeatureCollection GetAllFeaturesFromCurrentContentDb()
        {
            FeatureCollection toReturn = new FeatureCollection();
            try
            {
                LogHelper.TraceDebug("IN");
                foreach (var siteCollectionUrl in this.SiteCollectionUrls)
                {
                    Dictionary<Guid, string> featuresIntoCollection = new Dictionary<Guid, string>();
                    using (SPSite site = new SPSite(siteCollectionUrl))
                    {
                        foreach (SPFeature feature in site.Features)
                        {
                            Feature featureCandidateToAdd = MapFeature(site, feature);
                            toReturn.Add(featureCandidateToAdd);
                        }
                        foreach (SPWeb web in site.AllWebs)
                        {
                            foreach(SPFeature feature in web.Features)
                            {
                                Feature featureCandidateToAdd = MapFeature(web, feature);
                                toReturn.Add(featureCandidateToAdd);
                            }
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                LogHelper.TraceError(exc);
            }
            finally
            {
                LogHelper.TraceDebug("OUT");
            }
            return toReturn;
        }

     
        public override string CreateReport()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(CreateReportBanner("Feature Report"));
            sb.AppendLine(GetResolvedFeaturesInformations());
            return sb.ToString();
        }


        private static Feature MapFeature(SPSite site, SPFeature feature)
        {
            string featureDefintion = string.Empty;
            if (feature.Definition != null)
                featureDefintion = feature.Definition.GetXmlDefinition(System.Globalization.CultureInfo.CurrentCulture).OuterXml;
            Feature featureCandidateToAdd = new Feature()
            {
                ID = feature.DefinitionId,
                Definition = featureDefintion,
                InstalledUrl = site.Url,
                Scope = SharePointScope.Site
            };
            return featureCandidateToAdd;
        }

        private static Feature MapFeature(SPWeb web, SPFeature feature)
        {
            string featureDefintion = string.Empty;
            if (feature.Definition != null)
                featureDefintion = feature.Definition.GetXmlDefinition(System.Globalization.CultureInfo.CurrentCulture).OuterXml;
            Feature featureCandidateToAdd = new Feature()
            {
                ID = feature.DefinitionId,
                Definition = featureDefintion,
                InstalledUrl = web.Url,
                Scope = SharePointScope.Web
            };
            return featureCandidateToAdd;
        }

    }
}
